"""
# 格式：lambda arg1, arg2, ...argN : expression
add = lambda num1, num2: num1 + num2
print(add(2, 3))
print(type(add))
# 因为lambda表达式的形式，其可以放在列表中
list1 = [add, 1, 2]
print(list1[0](list1[1], list1[2]))
"""
import functools

'''
在函数结束时仍然保留函数值有三种方法
1.闭包
2.全局函数
3.生成器
生成器生成方法分为两种，一种是用yield替换return
另一种是列表生成式
'''


def add(num1, num2):
    for each in range(3):
        yield num1 + num2
        num1 += 1


# 函数返回了一个迭代器对象
print(add(2, 3))
for i in add(2, 3):
    print(i)
# 或者使用迭代器的专属函数next()
c = add(1, 3)
print(next(c))


def fnum():
    x = 0
    y = 1
    for i in range(3):
        yield x
        yield y
        x += y
        y += x


for each in fnum():
    print(each)

f = (i ** 2 for i in range(3))
print(next(f))


# 递归
def sum(num):
    if num == 1:
        return 1
    else:
        return num * sum(num - 1)


print(sum(10))


# 汉诺塔游戏解法，使用递归来做
def game(num: int) -> int:  # num代表的是层数
    """
    计算汉诺塔问题
    参数为层数
    返回步数值
    """
    if num == 1:
        return 1
    else:
        return game(num - 1) * 2 + 1


print(functools.reduce(game, [2, ]))


# 将可迭代对象中的值一个个传入到前面参数进行传参
# 隐函数，即闭包


def move_Temp(x1, y1):
    def move(fun):
        x = 0
        y = 0
        @functools.wraps(fun)
        def temp():
            nonlocal x, y
            if (x + x1) <= 100 and (y + y1 <= 100):
                x += x1
                y += y1
                print(f"当前的位置是 x = {x} , y = {y}")

        return temp

    return move


@move_Temp(1, 3)
def key_Move():
    print("开始移动")


print(key_Move.__name__)
